// 将observer和watcher关联起来，compile做dom节点的数据更新
function MVVM(options){
  this.$options = options || {};
  var data = this._data = this.$options.data; // 拿到对象类型options里的data对象。
  var that = this;

  // 数据代理，借助中间变量实现vm.xxx -> (代替以前的vm.data.xxx)
  // 也就是把vm.data.xxx 的key,挂载到this上去
  Object.keys(data).forEach( key => {
    that._proxyData(key);
  })

  this._initComputed(); // 初始化computed，（数据变化，更改数据时触发更新，待研究）

  observe(data, this); // 监听data对象上的所有属性，核心：Object.defineproperty()

  this.$compile = new Compile(options.el || document.body, this); // 拿到options里的el值，数据改变更新模板数据
}

MVVM.prototype = {
  $watch: function(key, cb, options) {
    new Watcher(this, key, cb);
  },

  _proxyData: function(key, setter, getter) {
    var that = this,
      setter = setter || 
      Object.defineProperty(that, key, {
        configurable: false,
        enumerable: true,
        get: function proxyGetter() {
          return that._data[key];
        },
        set: function proxySetter(newVal) {
          that._data[key] = newVal;
        }
      });
  },

  _initComputed: function() {
    var that = this;
    var computed = this.$options.computed;
    if(typeof computed === 'object'){
      Object.keys(computed).forEach(key => {
        Object.defineProperty(that, key, {
          get: typeof computed[key] === 'function' ? computed[key] : computed[key].get,
          set: function (){}
        })
      })
    }
  }
}